package com.kele.target22;

import lombok.Data;
import lombok.SneakyThrows;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
 * @author chunhui.li
 * @date 2022/2/6 21:31
 * @Description 继承的练习
 * @ClassName ExtendsTest
 */

@Data
public class ExtendsTest extends Person {
    private String school;

    /**
     * 总结：
     *   1.子类没有扩展的属性或者方法也可以使用父类的属性或者方法
     *   2.子类不能直接调用父类的私有属性或者私有方法 ：通过getter或者setter来调用
     *   3.子类调用方法时会在自己这边找没有才会调用父类的
     */
    @Override
    public void fun1() {
        System.out.println("子类重写父类");
    }

    @SneakyThrows
    public static void main(String[] args) throws InstantiationException{
        ExtendsTest extendsTest = new ExtendsTest();
        extendsTest.setAge(12);
        extendsTest.setName("kele");
        extendsTest.setSchool("wuhan");
        extendsTest.fun1();
        /**
         * 多态得验证
         *  1. 向上转型  当不需要面对子类类型时，通过提高扩展性，或者使用父类的功能就能完成相应的操作。
         *  2. 向下转型  当要使用子类特有功能时。
         */
        Person person =new ExtendsTest();
        person.fun3();
        /**
         * 反射操作父类
         */
        Class<Person> personClass = Person.class;
        /**
         * 反射拿到所有的方法
         */
        Method[] declaredMethods = personClass.getDeclaredMethods();
        /**
         * 拿到所有方法的名称和返回值类型
         */
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod.getName()+ " -> "+ Modifier.toString(declaredMethod.getModifiers()));
        }
        /**
         * 通过反射调用父类的指定方法
         */
        Method fun2 = personClass.getDeclaredMethod("fun2");
        fun2.setAccessible(true);
        fun2.invoke(extendsTest);

        System.out.println(extendsTest.getAge()+" ====> "+extendsTest.getName()+" ====> "+extendsTest.getSchool());
    }
}
@Data
class Person{
    private String name;
    private Integer age;

    private Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public Person(){}
    public Person setPerson(String name,Integer age) {
        return new Person(name,age);
    }
    private String getPserson(){
        return name + " and "+ age;
    }
    public void fun1(){
        System.out.println("父类公有");
    }

    private void fun2(){
        System.out.println("父类私有");
    }
    public  void fun3 (){
        System.out.println(123456);
    }
}
